﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using Castle.Core;
using NLog;
using Castle.Windsor;
using NGinnBPM.Lib.Interfaces;
using NGinnBPM.Services;
using NGinnBPM.Runtime;
using NGinnBPM.MessageBus;
using System.IO;
using NGinnBPM.MessageBus.Perf;
using System.Configuration;
using Reg = Castle.MicroKernel.Registration;
using System.Reflection;


namespace NGinnBPM.Engine.WindsorHost
{
    public partial class WindsorHostService : ServiceBase
    {
        protected Logger log = LogManager.GetCurrentClassLogger();
        private ServiceController serviceController1;
        protected INGinnHost _hst;
        public WindsorHostService()
        {
            
        }

        protected override void OnStart(string[] args)
        {
            log.Info("Starting");
            try
            {

                string basedir = Path.GetFullPath(Path.Combine(this.GetType().Assembly.Location, "..\\..\\.."));
                log.Info("Setting base dir to {0}", basedir);
                NGinnBPM.HostConfig.NGinnHostConfigurator configurator = NGinnBPM.HostConfig.NGinnHostConfigurator.BeginConfig();

                configurator.SetConfigFile("nginn.properties")
                    .FinishConfiguration();

                _hst = configurator.GetNGinnHost();

                IConfigParameterProvider cfg = _hst.ServiceLocator.GetInstance<IConfigParameterProvider>();
                string perfFile = cfg.GetString("NGinn.MessageBus.PerfCountersConfigFile", null);
                if (perfFile != null && perfFile.Length > 0)
                {
                    log.Info("Configuring performance counters from {0}", perfFile);
                    DefaultCounters.ConfigureFromFile(perfFile);
                }
                string remotingConfigFile = cfg.GetString("NGinnBPM.Host.RemotingConfigFile", "");
                if (remotingConfigFile != null && remotingConfigFile.Length > 0)
                {
                    if (File.Exists(remotingConfigFile))
                    {
                        log.Info("Configuring remoting from file: {0}", remotingConfigFile);
                        System.Runtime.Remoting.RemotingConfiguration.Configure(remotingConfigFile, false);
                    }
                    else
                        log.Warn("Remoting config file not found: {0}", remotingConfigFile);
                }
                configurator.RegisterNGinnHostForRemoting("NGinnHost.rem");


                //_hst.RegisterForRemoting();
                log.Info("Starting NGInn");
                _hst.Start();

            }
            catch (ReflectionTypeLoadException ex)
            {
                log.Error("Tyoe load error starting NGinn host service: {0}", ex);
                foreach(Exception e2 in ex.LoaderExceptions)
                {
                    log.Warn("Loader exception: {0}", e2);
                }
                throw;
            }
            catch (Exception ex)
            {
                log.Error("Error starting NGinn host service: {0}", ex);
                throw ex;
            }
        }

        protected override void OnStop()
        {
            try
            {
                log.Info("Stopping NGinn Host service");
                _hst.Stop();
                log.Info("NGinn stopped");
                //_hst.Dispose();
                _hst = null;
            }
            catch (Exception ex)
            {
                log.Error("Error stopping NGinn engine: {0}", ex);
                return;
            }
        }

        public void Start()
        {
            OnStart(null);
        }

        private void InitializeComponent()
        {
            this.serviceController1 = new System.ServiceProcess.ServiceController();
            // 
            // WindsorHostService
            // 
            this.ServiceName = "NGinnHost";

        }
    }
}
